package model;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 * Parse an XML file for use in the model.
 * 
 * @author Tommy Petrilak modified by Rex
 * 
 */
public class XMLParser extends Parser {

    private NodeList myXMLRoot;
    private NodeList myNodeList;

    /**
     * 
     * @param xmlFile xml file chosen by user
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     * @throws IOException input-output exception that occurs when reading
     */
    public XMLParser (File xmlFile) throws IOException {
        super(xmlFile);
    }

    /**
     * get field names and field types for each column
     * @param inputDataFile data file that has XML extension
     * @throws IOException input-output exception that occurs when reading
     */
    protected void readCategories (File inputDataFile) throws IOException {

        System.setProperty("javax.xml.parsers.DocumentBuilderFactory", 
                "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
        DocumentBuilder dBuilder = null;
        
        try {
            dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        }
        catch (ParserConfigurationException e) {
            System.err.println("config error");
            e.printStackTrace();
        }
        Document doc = null;
        try {
            doc = dBuilder.parse(inputDataFile);
        }
        catch (SAXException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
            throw e;
        }

        doc.getDocumentElement().normalize();
        myXMLRoot = doc.getElementsByTagName("metadata");
        NodeList myNodeList = myXMLRoot.item(0).getChildNodes();

        for (int j = 0; j < myNodeList.getLength(); j++) {
            Node nNode = myNodeList.item(j);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                Element eElement = (Element) nNode;
                if (!"".equals(eElement.getTextContent())) {
                    getFieldNames().add(eElement.getNodeName());
                    getFieldTypes().add(
                            determineType(eElement.getTextContent()));
                }
            }
        }
    }

    /**
     * read data in the table
     */
    @SuppressWarnings("rawtypes")
    public void readData () {
     // get date in the table
        for (int i = 1; i < myXMLRoot.getLength(); i++) {
            ArrayList<Comparable> rowData = new ArrayList<Comparable>();
            myNodeList = myXMLRoot.item(i).getChildNodes();
            for (int j = 0; j < myNodeList.getLength(); j++) {
                Node nNode = myNodeList.item(j);

                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;

                    if (!"".equals(eElement.getTextContent())) {
                        eElement.getChildNodes();
                        rowData.add(eElement.getTextContent());
                    }
                }
            }
            getTable().add(rowData);
        }
    }

    /**
     * @return result table
     */
    @Override
    public Table retrieveTable () {
        Table result = new Table(getTable(), getFieldTypes());
        return result;
    }
}
